0097. 交错字符串【中等】
1. 📝 题目描述
给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。
两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:
s = s1 + s2 + ... + snt = t1 + t2 + ... + tm|n - m| <= 1- 交错 是
s1 + t1 + s2 + t2 + s3 + t3 + ...或者t1 + s1 + t2 + s2 + t3 + s3 + ...
注意:a + b 意味着字符串 a 和 b 连接。
示例 1:

txt
输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出:true1
2
2
示例 2:
txt
输入:s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出:false1
2
2
示例 3:
txt
输入:s1 = "", s2 = "", s3 = ""
输出:true1
2
2
提示:
0 <= s1.length, s2.length <= 1000 <= s3.length <= 200s1、s2、和s3都由小写英文字母组成
进阶:您能否仅使用 O(s2.length) 额外的内存空间来解决它?
2. 🎯 s.1 - 动态规划(滚动数组)
c
bool isInterleave(char* s1, char* s2, char* s3) {
int m = strlen(s1), n = strlen(s2);
if (m + n != strlen(s3)) return false;
bool dp[n + 1];
memset(dp, false, sizeof(dp));
dp[0] = true;
for (int j = 1; j <= n; j++)
dp[j] = dp[j - 1] && s2[j - 1] == s3[j - 1];
for (int i = 1; i <= m; i++) {
dp[0] = dp[0] && s1[i - 1] == s3[i - 1];
for (int j = 1; j <= n; j++)
dp[j] = (dp[j] && s1[i - 1] == s3[i + j - 1]) ||
(dp[j - 1] && s2[j - 1] == s3[i + j - 1]);
}
return dp[n];
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
js
/**
* @param {string} s1
* @param {string} s2
* @param {string} s3
* @return {boolean}
*/
var isInterleave = function (s1, s2, s3) {
const m = s1.length,
n = s2.length
if (m + n !== s3.length) return false
const dp = new Array(n + 1).fill(false)
dp[0] = true
for (let j = 1; j <= n; j++) dp[j] = dp[j - 1] && s2[j - 1] === s3[j - 1]
for (let i = 1; i <= m; i++) {
dp[0] = dp[0] && s1[i - 1] === s3[i - 1]
for (let j = 1; j <= n; j++)
dp[j] =
(dp[j] && s1[i - 1] === s3[i + j - 1]) ||
(dp[j - 1] && s2[j - 1] === s3[i + j - 1])
}
return dp[n]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
py
class Solution:
def isInterleave(self, s1: str, s2: str, s3: str) -> bool:
m, n = len(s1), len(s2)
if m + n != len(s3): return False
dp = [False] * (n + 1)
dp[0] = True
for j in range(1, n + 1):
dp[j] = dp[j - 1] and s2[j - 1] == s3[j - 1]
for i in range(1, m + 1):
dp[0] = dp[0] and s1[i - 1] == s3[i - 1]
for j in range(1, n + 1):
dp[j] = (dp[j] and s1[i - 1] == s3[i + j - 1]) or \
(dp[j - 1] and s2[j - 1] == s3[i + j - 1])
return dp[n]1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 时间复杂度:
,其中 m 和 n 分别是 s1 和 s2 的长度 - 空间复杂度:
,滚动数组仅使用一维 dp
算法思路:
dp[j]表示s1的前i个字符和s2的前j个字符能否交错组成s3的前i+j个字符- 转移方程:当前字符可以来自
s1[i-1](从上方转移)或s2[j-1](从左方转移) - 若长度不匹配(
m + n ≠ len(s3)),直接返回false - 使用滚动数组优化空间,将二维 DP 压缩为一维